package cn.chinaflame.pagodas.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import cn.chinaflame.pagodas.Result.Result;
import cn.chinaflame.pagodas.utils.ScheduleTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.chinaflame.pagodas.constant.Constant;
import cn.chinaflame.pagodas.constant.Sysconst;
import cn.chinaflame.pagodas.entity.PaBalmOrder;
import cn.chinaflame.pagodas.entity.PaMember;
import cn.chinaflame.pagodas.enums.CodeEnum;
import cn.chinaflame.pagodas.repository.PaBalmOrderRepository;
import cn.chinaflame.pagodas.repository.PaMemberRepository;
import cn.chinaflame.pagodas.req.PaBalmOrderAddReq;
import cn.chinaflame.pagodas.req.PaydataReq;
import cn.chinaflame.pagodas.utils.DateTimes;
import cn.chinaflame.pagodas.utils.MapHeadUtil;
import cn.chinaflame.pagodas.utils.ParamPreconditions;
import cn.chinaflame.pagodas.utils.stl.Base64Util;
import cn.chinaflame.pagodas.utils.stl.HttpClientUtils;
import cn.chinaflame.pagodas.utils.stl.JsonUtil;
import cn.chinaflame.pagodas.utils.stl.MD5Util;
import cn.chinaflame.pagodas.utils.stl.MapUtil;

/**
* @author    created by lbq
* @date	     2018年7月25日 上午11:29:56
**/
@Service
public class PaBalmOrderService {

	private static Logger logger = LoggerFactory.getLogger(PaBalmOrderService.class);

	private static Map<String, String> param = new HashMap<String, String>();
	
	@Autowired
	private PaBalmOrderRepository paBalmOrderRepository;
	@Autowired
    private  IdGeneratorService idGeneratorService;
	@Autowired
	private PaMemberRepository paMemberRepository;
	@Autowired
	private YwPayApiService ywPayApiService;
	@Autowired
	private PaDonatrGoodsService paDonatrGoodsService;
	
	/**
	 * 香油下单接口
	 * @param req
	 * @return
	 * @throws Exception
	 */
	public Object addOrder(PaBalmOrderAddReq req) throws Exception{
		PaBalmOrder paBalmOrder=new PaBalmOrder();
		String id= idGeneratorService.generatePaBalmOrderId();
		paBalmOrder.setId(id);
		paBalmOrder.setOpenid(req.getOpenid());
		paBalmOrder.setMobile(req.getMobile());
		paBalmOrder.setOrderType("1");
		paBalmOrder.setMoney(req.getMoney());
		paBalmOrder.setPayStatus(Sysconst.PAY_STATUS_DOING);
		paBalmOrder.setPayType("WECHAT");
		paBalmOrder.setPayTime(DateTimes.nowDateTime());
		paBalmOrder.setAddTime(DateTimes.nowDateTime());
		paBalmOrder.setOrderId(req.getOrderId());
		paBalmOrder.setCreatetime(DateTimes.nowDateTime());
		paBalmOrder.setUpdatetime(DateTimes.nowDateTime());
		paBalmOrderRepository.saveAndFlush(paBalmOrder);
		
		PaydataReq payReq = new PaydataReq();
		payReq.setOrderNo(id);
		payReq.setOrderAmount(String.valueOf(req.getMoney()));
		payReq.setAcct(req.getOpenid());
		return ywPayApiService.YsWxjsapiPay1(payReq);
//		String  msg=  pay(paBalmOrder.getId());
	}

	public Object syjzAdd(PaBalmOrderAddReq req) {
		logger.info("随缘捐赠订单添加service req{}",req);
		try{
			paDonatrGoodsService.stock(req.getGoodsId(),1,"1");
			PaBalmOrder paBalmOrder=new PaBalmOrder();
			String id= idGeneratorService.generatePaBalmOrderId();
			paBalmOrder.setId(id);
			paBalmOrder.setOpenid(req.getOpenid());
			paBalmOrder.setMobile(req.getMobile());
			paBalmOrder.setOrderType("2");
			paBalmOrder.setMoney(req.getMoney());
			paBalmOrder.setPayStatus(Sysconst.PAY_STATUS_DOING);
			paBalmOrder.setPayType("WECHAT");
			paBalmOrder.setPayTime(DateTimes.nowDateTime());
			paBalmOrder.setAddTime(DateTimes.nowDateTime());
			paBalmOrder.setOrderId(req.getOrderId());
			paBalmOrder.setCreatetime(DateTimes.nowDateTime());
			paBalmOrder.setUpdatetime(DateTimes.nowDateTime());
			paBalmOrderRepository.saveAndFlush(paBalmOrder);
			new Thread(new Runnable() {
				@Override
				public void run() {
					logger.info("线程启动");
					new PaBalmOrder(id, new ScheduleTime(30, TimeUnit.MINUTES),Sysconst.PAY_STATUS_WAIT);
				}
			}).start();
			return Result.create("添加成功");
		}catch (Exception e){

		}
		return Result.create("FALSE","随缘捐赠订单添加失败");
	}
	
	/**
	 * 下完单支付
	 * @param id
	 * @return
	 * @throws Exception 
	 */
	public String pay(String id) throws Exception{
		PaBalmOrder balmOrder=paBalmOrderRepository.findBalmById(id);
		ParamPreconditions.checkNotNull(balmOrder, CodeEnum.FAIL.getCode(),"没有此订单");
		PaMember member=paMemberRepository.findByMobile(balmOrder.getMobile());
		ParamPreconditions.checkNotNull(member, CodeEnum.FAIL.getCode(),"没有此会员");
		
		// 设置请求头
		Map<String, String> headMap= MapHeadUtil.headMap(balmOrder.getId());
		// 设置请求正文
		Map<String, String> contentMap = new LinkedHashMap<String, String>();
		contentMap.put("customerIP", "192.168.1.1");
		contentMap.put("orderAmount", balmOrder.getMoney().multiply(new BigDecimal(100)).setScale(0, RoundingMode.UNNECESSARY)+"");
		contentMap.put("displayName", "fokan");
		contentMap.put("goodsName", "香油");
		contentMap.put("goodsCount", "1");
		contentMap.put("payType", "js");//js 微信公众号  qrcode扫码 
		contentMap.put("orgCode", "wechatpay");//目标资金机构代码： 1.alipay支付宝  2.wechatpay微信 
		contentMap.put("directFlag", "1");
		contentMap.put("channelCode", "");
		contentMap.put("platformId", "");//商户所属平台商编号 暂时为空
		contentMap.put("returnUrl", "http://192.168.1.135:18006");//商户回调地址
		contentMap.put("noticeUrl", "http://buddhatower.happyworlds.cn/openapi/v1/pagodas/balm/noticeUrl");//商户通知地址 后台
		contentMap.put("buyerId", member.getOpenid());//买家为支付宝（user_Id）买家为微信（open_id）
		contentMap.put("remark", "香油测试");
		//签名
		Map<String, Object> signMap = new LinkedHashMap<String, Object>();
		signMap.put("head", headMap);
		signMap.put("content", contentMap);

		String signStr = JsonUtil.toJSonString(signMap);
		System.out.println("signStr:" + signStr);
		String strMd5 = MD5Util.md5Hex(signStr);
		String sign =strMd5 +Constant.publicKey;
		System.out.println("待进行MD5源串:" + sign);
		sign = MD5Util.md5Hex(sign);
		System.out.println("查看签名"+sign);
		Map<String, Object> paraMap = new LinkedHashMap<String, Object>();
		paraMap.put("head", headMap);
		paraMap.put("content", contentMap);
		paraMap.put("sign", sign);
		String jsonStr = JsonUtil.toJSonString(paraMap);
		System.out.println("提交串：" + jsonStr);
		String msg = new String(Base64Util.encode(jsonStr.getBytes()));
		msg = URLEncoder.encode(msg, "utf-8");
		param.put("msg", msg);
		String params = MapUtil.map2string(param); 
		System.out.println("提交参数：" + params);
		String resultStr = HttpClientUtils.sendPost(Constant.REQ_URL, params);
		
		System.out.println("同步提交返回：" + resultStr);
		msg = resultStr.substring(4);
		Map content= PayJsApiService.parse(msg);
		String responseCode= (String) content.get("responseCode");
		if(responseCode.equals("0001")){
			//发送支付后修改订单状态
			balmOrder.setPayStatus("1");
			balmOrder.setUpdatetime(DateTimes.nowDateTime());
			balmOrder.setPayTime(DateTimes.nowDateTime());
			paBalmOrderRepository.saveAndFlush(balmOrder);
		} else{
			return "ERROR";
		}
		
		return (String) content.get("codeUrl");
	}
	
	
	/**
	 * 接收后台通知
	 * 
	 * @param request
	 * @return
	 */
	public String notifyBkgUrl(HttpServletRequest request) {
		System.out.println("************************* 接收到后台通知 *****************************");
		String msg = request.getParameter("msg");
		System.out.println("接收到通知能数：msg=" + msg);
		// 进行验签
		try {
			String msg1 = new String(Base64Util.decode(msg.getBytes()), "UTF-8");
			System.out.println("base64解签后：" + msg1);
			
			Map<String, Object> jsonMap = JsonUtil.jsonToMap(msg1);
			Map head = (Map) jsonMap.get("head");
			Map content = (Map) jsonMap.get("content");
			String sign = (String) jsonMap.get("sign");

			Map<String, Object> signMap = new HashMap();
			signMap.put("head", head);
			signMap.put("content", content);

			String signStr = JsonUtil.toJSonString(signMap);
			System.out.println("signStr:" + signStr);
			
			String strMd5 = MD5Util.md5Hex(signStr);
			
			String  signVal = strMd5 + Constant.publicKey;
			signVal = MD5Util.md5Hex(signVal);
			//System.out.println("验签前的值：" + signVal);
			//System.out.println("验签结果：" + sign.equalsIgnoreCase(signVal));
			ParamPreconditions.checkArgument(sign.equalsIgnoreCase(signVal), CodeEnum.FAIL.getCode(), "验签失败");
			
			updateOrder(content.get("merOrderId").toString(), content.get("stateCode").toString());//拿到清结算返回的订单id和状态
			
		} catch (Exception e) {
			System.out.println("验签异常;" + e);
			// 返回
			return String.valueOf("FAIL");
		}

		return String.valueOf("OK");
	}
	/**
	 * 修改订单状态
	 * @param id
	 * @param state
	 */
	public void updateOrder(String id,String state){
		PaBalmOrder balmOrder=paBalmOrderRepository.findBalmById(id);
		ParamPreconditions.checkNotNull(balmOrder, CodeEnum.FAIL.getCode(),"没有此订单");
		if(Objects.equals(state,"2")){
			balmOrder.setPayStatus("2");
			balmOrder.setPayFinishTime(DateTimes.nowDateTime());
			balmOrder.setUpdatetime(DateTimes.nowDateTime());
		} else {
			balmOrder.setErrorMsg("处理失败");
			balmOrder.setUpdatetime(DateTimes.nowDateTime());
		}
		paBalmOrderRepository.saveAndFlush(balmOrder);
	}
	
	
	
	
	
	
	
	
	
	
}
